El siguiente proyecto tiene como finalidad hacer un análisis exploratorio sobre los datos históricos de los meses de enero hasta julio del año 2018 proporcionados por la página de ecobici; en la misma liga se puede econtrar lo necesario para accesar al API proporcionado por este servicio. La documentación sobre la API se encuentra en la siguiente liga
Ecobici es un servicio de bicicletas públicas de la Ciudad de México dirigido a los habitantes de la capital, de sus alrededores y a los turistas.
El funcionamiento de este servicio permite a los usuarios registrados tomar una bicicleta de cualquier cicloestación y devolverla en la más cercana a su destino en trayectos ilimitados de 45 minutos.
La forma para acceder a este servicio es mediante un suscripción anual, semanal, de cada tres días o diaria
Este servicio está disponible en un horario de 5:00 hrs hasta 00:30 hrs todos los días del año, el cuál inicio en el año 2010, febrero con 84 cicloestaciones y mil 200 bicicletas.
Actualmente Ecobici cuenta con más de 170 mil usuarios registrados y el servicio está disponible en 55 colonias de la Ciudad de México, en un área de 38 kilómetros cuadrados.
El API de ecobicise enfoca en datos actuales y el objetivo es sobre los datos históricos, para su obtención no es necesario utilizar la API.
Los datos fueron descargados y almacenados en una BD llamada ECOBICI; el dump para exportar esta BD se encuentra en los archivos suministrados en este proyecto en la carpeta data
La BD ECOBICI contiene 7 tablas, una por cada mes, es decir, una por cada archivo descargado directamente de la página de ecobici; cada tabla contiene los siguientes campos:
El siguiente código sirve para acceder a una base de datos de MySQL, sin embargo lo que yo utilicé fue directamente de archivos Excel y construcción de Data Frames ¿Por qué? Porque utilizo la computadora del trabajo que tiene algunas restricciones para copiar archivos directamente de Excel en base de datos.
library(readr)
library(ggplot2)
library(stringr)
library(dplyr)
library(knitr) #para generar una tabla cool en el reporte
library(tidyr) #para manipulacion de datos
library(lubridate)
library(ggmap)
library(plotly)
library(tidyverse)
library(RMySQL)
library(pool)
library(DBI)Si me hubiera conectado a una base de datos:
Se procederá a la conexión y extracción de datos desde la BD
"[db.host <- 'localhost'
db.user <- 'root'
db.port <- 3306
db.password <- 'Calderon260'
## DB Connection
db_connect <- function(db.name) {
db <- dbPool(
drv = RMySQL::MySQL(),
dbname = db.name,
host = db.host,
user = db.user,
password = db.password,
port = as.numeric(db.port)
)
return(db)
}]"## [1] "[db.host <- 'localhost'\ndb.user <- 'root'\ndb.port <- 3306\ndb.password <- 'Calderon260'\n\n## DB Connection\ndb_connect <- function(db.name) {\n db <- dbPool(\n drv = RMySQL::MySQL(),\n dbname = db.name,\n host = db.host,\n user = db.user,\n password = db.password,\n port = as.numeric(db.port)\n )\n \n return(db)\n}]"
Nos interesa hacer un análisis sobre todos los datos por lo que, para evitar seleccionar todo por partes de cada tabla, se extraeran todos los datos de cada tabla.
"[
January <- tbl(db_connect('ECOBICI'), 'Enero') %>% collect()
February <- tbl(db_connect('ECOBICI'), Febrero') %>% collect()
March <- tbl(db_connect('ECOBICI'), Marzo) %>% collect()
April <- tbl(db_connect('ECOBICI'), Abril) %>% collect()
May <- tbl(db_connect('ECOBICI'), 'Mayo') %>% collect()
June <- tbl(db_connect('ECOBICI'), 'Junio') %>% collect()
July <- tbl(db_connect('ECOBICI'), 'Julio') %>% collect()
]"## [1] "[\nJanuary <- tbl(db_connect('ECOBICI'), 'Enero') %>% collect()\nFebruary <- tbl(db_connect('ECOBICI'), Febrero') %>% collect()\nMarch <- tbl(db_connect('ECOBICI'), Marzo) %>% collect()\nApril <- tbl(db_connect('ECOBICI'), Abril) %>% collect()\nMay <- tbl(db_connect('ECOBICI'), 'Mayo') %>% collect()\nJune <- tbl(db_connect('ECOBICI'), 'Junio') %>% collect()\nJuly <- tbl(db_connect('ECOBICI'), 'Julio') %>% collect()\n]"
Como yo leí la información directamente de los archivos de excel :
January <- read_csv("data/2018-01.csv",col_names = T, na = c(""," ", "NA", "?"))
February <- read_csv("data/2018-02.csv",col_names = T, na = c(""," ", "NA", "?"))
March <- read_csv("data/2018-03.csv",col_names = T, na = c(""," ", "NA", "?"))
April <- read_csv("data/2018-04.csv",col_names = T, na = c(""," ", "NA", "?"))
May <- read_csv("data/2018-05.csv",col_names = T, na = c(""," ", "NA", "?"))
June <- read_csv("data/2018-06.csv",col_names = T, na = c(""," ", "NA", "?"))
July <- read_csv("data/2018-07.csv",col_names = T, na = c(""," ", "NA", "?"))
names(January) <- tolower(names(January))
names(February) <- tolower(names(February))
names(March) <- tolower(names(March))
names(April) <- tolower(names(April))
names(May) <- tolower(names(May))
names(June) <- tolower(names(June))
names(July) <- tolower(names(July))Ahora, un poco de limpieza
JanuaryCon la siguiente función se modificará el tipo de dato en genero_usuario y se colapsará los datos de tiempo y fecha en un sólo dato para los tiempos de arrivo y los tiempos de retiro registrados
gender_arr_fix <- function(data){
new_data <- data %>%
mutate(genero_usuario = factor(genero_usuario, levels = c("M", "F")),
hora_arribo = str_replace(hora_arribo, "(\\w+:\\w+:\\w+)\\r", "\\1"),
fecha_retiro = dmy(fecha_retiro),
hora_retiro = hms(hora_retiro),
fecha_arribo = dmy(fecha_arribo),
hora_arribo = hms(hora_arribo)
) %>%
mutate(re_datetime = make_datetime(year(fecha_retiro),
month(fecha_retiro),
day(fecha_retiro),
hour(hora_retiro),
minute(hora_retiro),
second(hora_retiro)),
arr_datetime = make_datetime(year(fecha_arribo),
month(fecha_arribo),
day(fecha_arribo),
hour(hora_arribo),
minute(hora_arribo),
second(hora_arribo))) %>%
select(-c(fecha_retiro, hora_retiro, fecha_arribo, hora_arribo))
return(new_data)
}Modificamos la tabla con la función previamente creada
January <- gender_arr_fix(January)
February <- gender_arr_fix(February)
March <- gender_arr_fix(March)
April <- gender_arr_fix(April)
May <- gender_arr_fix(May)
June <- gender_arr_fix(June)
July <- gender_arr_fix(July)JulyPara realizar un perfilamiento de datos se hace uso del módulo `DataProfiling el cual se encuentra en los documentos de este proyecto.
source("DataProfiling.R")Ahora, se hará el data profiling por cada mes
Hay que observar que edad_usuario, id_bici, ciclo_estacion_retiro, ciclo_estacion_arribo son identificadores, por lo que, aunque sean de tipo numérico, no proporcionan alguna información cuantitativa relevante, por lo que solo se observarán características sobre los datos que no incluya resumenes numericos.
Primero un conteo de datos y después un resumen por cada mes.
Jan_fac <- January %>% select(-c(re_datetime, arr_datetime))
Jan_date <- January %>% select(c(re_datetime, arr_datetime))Se construye una tabla con especificaciones de formato, que los números muy grandes los separe con “,” y que no utilice notación científica
Jan_factor <- Jan_fac %>% profiling("categorical")
kable(Jan_factor, format.args = list(big.mark=",", scientific=F))| uniques | nan | mode | |
|---|---|---|---|
| genero_usuario | 2 | 0 | M |
| edad_usuario | 67 | 0 | 28 |
| bici | 4,897 | 1 | 7376 |
| ciclo_estacion_retiro | 432 | 0 | 271 |
| ciclo_estacion_arribo | 435 | 0 | 1 |
Para los datos de tiempo sólo se verifica si existen valores nulos y el conteo de los valores únicos.
Jan_datetime <- Jan_date %>% profiling("other")
kable(Jan_datetime, format.args = list(big.mark=",", scientific=F))| uniques | nan | |
|---|---|---|
| re_datetime | 545,217 | 0 |
| arr_datetime | 545,660 | 0 |
| Y no hay valore | s nulos |
Feb_fac <- February %>% select(-c(re_datetime, arr_datetime))
Feb_date <- February %>% select(c(re_datetime, arr_datetime))
Feb_factor <- Feb_fac %>% profiling("categorical")
kable(Feb_factor, format.args = list(big.mark=",", scientific=F))| uniques | nan | mode | |
|---|---|---|---|
| genero_usuario | 2 | 0 | M |
| edad_usuario | 73 | 0 | 28 |
| bici | 5,058 | 44 | 2019 |
| ciclo_estacion_retiro | 476 | 0 | 271 |
| ciclo_estacion_arribo | 476 | 0 | 43 |
Feb_datetime <- Feb_date %>% profiling("other")
kable(Feb_datetime, format.args = list(big.mark=",", scientific=F))| uniques | nan | |
|---|---|---|
| re_datetime | 541,252 | 0 |
| arr_datetime | 541,095 | 0 |
Mar_fac <- March %>% select(-c(re_datetime, arr_datetime))
Mar_date <- March %>% select(c(re_datetime, arr_datetime))
Mar_factor <- Mar_fac %>% profiling("categorical")
kable(Mar_factor, format.args = list(big.mark=",", scientific=F))| uniques | nan | mode | |
|---|---|---|---|
| genero_usuario | 2 | 0 | M |
| edad_usuario | 72 | 0 | 28 |
| bici | 4,931 | 122 | 2698 |
| ciclo_estacion_retiro | 476 | 0 | 271 |
| ciclo_estacion_arribo | 478 | 0 | 27 |
Mar_datetime <- Mar_date %>% profiling("other")
kable(Mar_datetime, format.args = list(big.mark=",", scientific=F))| uniques | nan | |
|---|---|---|
| re_datetime | 580,412 | 0 |
| arr_datetime | 579,596 | 0 |
A_fac <- April %>% select(-c(re_datetime, arr_datetime))
A_date <- April %>% select(c(re_datetime, arr_datetime))
A_factor <- A_fac %>% profiling("categorical")
kable(A_factor, format.args = list(big.mark=",", scientific=F))| uniques | nan | mode | |
|---|---|---|---|
| genero_usuario | 2 | 0 | M |
| edad_usuario | 71 | 0 | 28 |
| bici | 4,889 | 132 | 11065 |
| ciclo_estacion_retiro | 478 | 0 | 27 |
| ciclo_estacion_arribo | 478 | 0 | 27 |
A_datetime <- A_date %>% profiling("other")
kable(A_datetime, format.args = list(big.mark=",", scientific=F))| uniques | nan | |
|---|---|---|
| re_datetime | 589,901 | 0 |
| arr_datetime | 589,669 | 0 |
May_fac <- May %>% select(-c(re_datetime, arr_datetime))
May_date <- May %>% select(c(re_datetime, arr_datetime))
May_factor <- May_fac %>% profiling("categorical")
kable(May_factor, format.args = list(big.mark=",", scientific=F))| uniques | nan | mode | |
|---|---|---|---|
| genero_usuario | 2 | 0 | M |
| edad_usuario | 72 | 0 | 28 |
| bici | 4,982 | 0 | 15259 |
| ciclo_estacion_retiro | 480 | 0 | 271 |
| ciclo_estacion_arribo | 480 | 0 | 27 |
May_datetime <- May_date %>% profiling("other")
kable(May_datetime, format.args = list(big.mark=",", scientific=F))| uniques | nan | |
|---|---|---|
| re_datetime | 618,668 | 0 |
| arr_datetime | 618,486 | 0 |
La estación más concurrida para dejar una bicicleta fue la 27
Junio
Jun_fac <- June %>% select(-c(re_datetime, arr_datetime))
Jun_date <- June %>% select(c(re_datetime, arr_datetime))
Jun_factor <- Jun_fac %>% profiling("categorical")
kable(Jun_factor, format.args = list(big.mark=",", scientific=F))| uniques | nan | mode | |
|---|---|---|---|
| genero_usuario | 2 | 0 | M |
| edad_usuario | 71 | 0 | 28 |
| bici | 4,980 | 0 | 2789 |
| ciclo_estacion_retiro | 479 | 0 | 271 |
| ciclo_estacion_arribo | 479 | 0 | 27 |
Jun_datetime <- Jun_date %>% profiling("other")
kable(Jun_datetime, format.args = list(big.mark=",", scientific=F))| uniques | nan | |
|---|---|---|
| re_datetime | 545,135 | 0 |
| arr_datetime | 545,241 | 0 |
La estación más concurrida para dejar una bicicleta fue la 27
Julio
July_fac <- July %>% select(-c(re_datetime, arr_datetime))
July_date <- July %>% select(c(re_datetime, arr_datetime))
July_factor <- July_fac %>% profiling("categorical")
kable(July_factor, format.args = list(big.mark=",", scientific=F))| uniques | nan | mode | |
|---|---|---|---|
| genero_usuario | 2 | 0 | M |
| edad_usuario | 70 | 0 | 28 |
| bici | 4,929 | 0 | 9581 |
| ciclo_estacion_retiro | 480 | 0 | 27 |
| ciclo_estacion_arribo | 480 | 0 | 27 |
July_datetime <- July_date %>% profiling("other")
kable(July_datetime, format.args = list(big.mark=",", scientific=F))| uniques | nan | |
|---|---|---|
| re_datetime | 568,438 | 0 |
| arr_datetime | 569,168 | 0 |
Vease que la estación número 271 es la que tiene un mayor número de registros donde los usuarios tomaron una biclceta en los meses de :
Por otro lado, la estación 27 en los meses de Abril y Julio es donde se obtienen la mayor cantidad de registros donde los usuarios tomaron una bicicleta. Esta estación es tienen la mayoría donde los usuarios depositaron una bicicleta en los meses de :
Ahora, surgen varias preguntas o issues sobre los datos.
A continuación se presenta un análisis exploratorio.
¿Dónde se ubican las estaciones más 27 y 271, así como la 1 y 43?
Un mapa de todas las cicloestaciones se encuentra en la página oficial de ecobici, aunque en esta liga se encuentra el archivo correspondiente.
La ubicación de cada una de las 480 estaciones se encuentra en la siguiente página
O bien se puede conseguir desde la API, donde se necesita un access token, obtenido de las credenciales propias de cada usuario, este access token tiene tiempo de vida de una hora. (poner en navegador https://pubsbapi.smartbike.com/oauth/v2/token?client_id=585_5oct79smo5s8kk0ksggkg0sokkkwwk00o0ssw4ww840gg04owc&clien t_secret=il6ccw6rdtkwo00cwoc44w4c8wgc4084g4gosowws004k888g&grant_type=client_credentials)
Interacción con API
#install.packages(httr)
# library(httr)
# ecobici_api <- function(path) {
# url <- modify_url("https://pubsbapi.smartbike.com", path = path)
#
# resp <- GET(url)
# if (http_type(resp) != "application/json") {
# stop("API did not return json", call. = FALSE)
# }
#
# parsed <- jsonlite::fromJSON(content(resp, "text"), simplifyVector = FALSE)
#
# if (http_error(resp)) {
# stop(
# sprintf(
# "Ecobici API request failed [%s]\n%s\n<%s>",
# status_code(resp),
# parsed$message,
# parsed$documentation_url
# ),
# call. = FALSE
# )
# }
#
# structure(
# list(
# content = parsed,
# path = path,
# response = resp
# ),
# class = "ecobici_api"
# )
# }
#
# print.ecobici_api <- function(x, ...) {
# cat("<Ecobici ", x$path, ">\n", sep = "")
# str(x$content)
# invisible(x)
# }
#
# ecobici_api("/api/v1/stations.json?access_token=OTcyMmJkYjUxYWM4MzQzMjQ0YTU3Njk3MjNkYzkyNWJmYzIwNjVkZTcyYTJlMjM3Yzg3NmQ1YTUwZGY2MGFmYg")Las anteriores estaciones son las siguientes:
# first_station <- geocode('Paseo de la Reforma y Havre, Juárez, 06600 Ciudad de México, Ciudad de México, México',
# source = "google")
# map_first_station <- get_map(location = as.numeric(first_station),
# color = "color",
# maptype = "roadmap",
# scale = 2,
# zoom = 16)
# ggmap(map_first_station) + geom_point(aes(x = lon, y = lat),
# data = first_station , colour = 'green',
# shape = 20, size = 10, fill= "green")# second_station <- geocode('Jesús García 271, Buenavista, 06350 Ciudad de México, CDMX, México',
# source = "google")
#
# map_second_station <- get_map(location = as.numeric(second_station),
# color = "color",
# maptype = "roadmap",
# scale = 2,
# zoom = 16)
#
# ggmap(map_second_station) + geom_point(aes(x = lon, y = lat),
# data = second_station , colour = 'green',
# shape = 20, size = 10, fill= "green")# third_station <- geocode('Rio Sena y Rio balsas, Ciudad de México, CDMX, México',
# source = "google")
#
# map_third_station <- get_map(location = as.numeric(third_station),
# color = "color",
# maptype = "roadmap",
# scale = 2,
# zoom = 16)
#
# ggmap(map_third_station) + geom_point(aes(x = lon, y = lat),
# data = third_station , colour = 'green',
# shape = 20, size = 10, fill= "green")# fourth_station <- geocode('Juarez y Revillagigedo, Ciudad de México, CDMX, México',
# source = "google")
#
# map_fourth_station <- get_map(location = as.numeric(fourth_station),
# color = "color",
# maptype = "roadmap",
# scale = 2,
# zoom = 16)
#
# ggmap(map_fourth_station) + geom_point(aes(x = lon, y = lat),
# data = fourth_station , colour = 'green',
# shape = 20, size = 10, fill= "green")La estación con más concurrencia fue la que estaba ubicada sobre reforma, cerca de Reforma 222, que es una plaza comercial y centro de trabajo.
Dos estaciones se ubican cerca del metro Buenavista, donde es un punto de conexión entre mucha gente que viene del Estado de México y otras partes de la Ciudad de México para viajar a las zonas donde se encuentra la mayor densidad de empleos.
Por último la estación 43, que en el momento de escribir esto, se encuentra fuera de operación, sin embargo es de mucha concurrencia al tener cercanía con Reforma y el centro.
Para tener todos los datos recabados en los meses de enero hasta julio del 2018, se junta todo para así obtener el tiempo promedio que los usuarios utilizan el servicio de ecobici de todas las estaciones con usabilidad registrada.
historicos_ecobici <- rbind(January, February, March, April, May, June, July)Ahora se agrega el tiempo que un usuario utilizo alguna bicicleta:
historicos_ecobici <- historicos_ecobici %>%
mutate(duracion = as.duration(arr_datetime-re_datetime))
historicos_ecobiciSi se ordenan estos datos por el tiempo de uso por usuario:
historicos_ecobici <- historicos_ecobici %>% arrange(duracion)Hay registros donde los usuarios tardaron 0 y hasta 1 segundo en dejar una bicicleta en estaciones distintas, esto es posiblemente debido a dos cosas principalmente:
1.- Si tu ecobici no la encuentras en buen funcionamiento, tienes hasta 2 minutos para regresarla. 2.- Hay veces en que tomas la ecobici y se te cae por descuido, así que debes solicitar una de nuevo.
historicos_ecobici %>% arrange(desc(duracion)) %>% filter(ciclo_estacion_retiro != ciclo_estacion_arribo)Hay registros donde los usuarios tardaron hasta 1.53 años en devolver una bicicleta, también semanas y hasta días.
Para evitar tomar datos donde los usuarios tuvieron algun error, o devolvieron la ecobici, o tardaron más de lo reglamentado, se tomaron aquellos datos con una duración a 30 segundos de una estación a otra y aquellos que cumplan con el reglamento establecido de ecobici en cuanto a la duración de 45 minutos.
new_historicos_ecobici <- historicos_ecobici %>% filter(duracion <= dminutes(45))
new_historicos_ecobici <- new_historicos_ecobici %>% filter(dseconds(30) <= duracion)
new_historicos_ecobici %>% arrange(duracion)new_historicos_ecobici <- new_historicos_ecobici %>% arrange(desc(duracion))
new_historicos_ecobicipromedio_tiempo_uso <- mean(new_historicos_ecobici$duracion)
promedio_tiempo_uso <- minute(seconds_to_period(round(promedio_tiempo_uso)))
print(str_c("El promedio de tiempo de uso de una ecobici dentro del tiempo reglamentario, en la Ciudad de México es de: ", promedio_tiempo_uso, " minutos"))## [1] "El promedio de tiempo de uso de una ecobici dentro del tiempo reglamentario, en la Ciudad de México es de: 13 minutos"
Con esta nueva limpieza, obtenemos aquellos registros entre las dos estaciones de estudio (271, 27, 1 y 43)
new_historicos_ecobici %>%
filter(ciclo_estacion_retiro %in% c(1, 43, 27, 271) | ciclo_estacion_retiro %in% c(1, 43, 27, 271)) Continuando con algunos otros datos, la siguiente gráfica muestra la proporción sobre el uso del servicio ecobici por edades registradas.
Por convención, se omitirán aquellos datos en el cual la edad es mayor a 85 años
new_historicos_ecobici %>%
filter(edad_usuario < 85) %>%
group_by(edad_usuario) %>%
dplyr::summarise(count = n()) %>%
mutate(proportion = count/sum(count)) %>%
ggplot(aes(x = edad_usuario, y = proportion, fill = proportion)) +
geom_bar(stat = "identity") +
ggtitle("Proporción de uso del servicio sobre la edad de los usuarios ")Esto servirá para saber cuando se requiere mayor demanda de servicio y mayor disponibilidad de bicicletas. Se utiliza el parámetro re_datetime porque es la hora en la cual los usuarios comienzan a usar una bicicleta, que no debería variar mucho a lo largo del día coparado con arr_datetime, porque el tiempo de uso con las nuevas tablas es de menos de 45 minutos.
por_hora_del_dia <- new_historicos_ecobici %>%
mutate(hora = hour(re_datetime)) %>%
group_by(hora) %>%
dplyr::summarise(conteo = n()) %>%
ggplot(aes(x = hora, y = conteo, fill = conteo)) +
geom_bar(stat = "identity")+
ggtitle("Cantidad de usuarios activos por hora que toman una ecobici")
ggplotly(por_hora_del_dia)por_hora_del_dia <- new_historicos_ecobici %>%
mutate(hora = hour(arr_datetime)) %>%
group_by(hora) %>%
dplyr::summarise(conteo = n()) %>%
ggplot(aes(x = hora, y = conteo, fill = conteo)) +
geom_bar(stat = "identity")+
ggtitle("Cantidad de usuarios activos por hora que dejan una ecobici")
ggplotly(por_hora_del_dia)Para tener los datos de cuales son las 10 horas donde hay mayor demanda de cobici se cuentan los usuarios por hora:
new_historicos_ecobici %>%
mutate(hora = hour(re_datetime)) %>%
group_by(hora) %>%
dplyr::summarise(conteo = n()) %>%
arrange(desc(conteo)) %>%
head(10)## # A tibble: 10 x 2
## hora conteo
## <int> <int>
## 1 18 483166
## 2 8 478318
## 3 19 391346
## 4 9 370395
## 5 17 353746
## 6 14 348941
## 7 15 347330
## 8 16 287176
## 9 13 286461
## 10 7 261877
Es curioso que estas horas coincidan con la hora habitual para entrar y salir de trabajar en la Ciudad de México, lo que tiene sentido, porque mucha gente va al trabajo en estos vehículos.
Para finalizar, algunas preguntas sobre el genero de los usuarios.
Falta un análisis de realizar y es para saber qué días de la semana tienen mayor demanda de bicicletas, por la cantidad de usuarios que toman alguna
por_dia_semana <- new_historicos_ecobici %>%
mutate(dia_semana = format(as.Date(re_datetime),"%A")) %>%
group_by(dia_semana) %>%
dplyr::summarise(conteo = n()) %>%
arrange(desc(conteo))
por_dia_semana## # A tibble: 7 x 2
## dia_semana conteo
## <chr> <int>
## 1 Tuesday 900937
## 2 Wednesday 895546
## 3 Thursday 865172
## 4 Monday 822882
## 5 Friday 815889
## 6 Saturday 374238
## 7 Sunday 323518
dias_sem <- ggplot(por_dia_semana, aes(x=dia_semana, y=conteo, fill= dia_semana)) +
geom_bar(stat = "identity")+
ggtitle("Cantidad de usuarios por día de la semana")
ggplotly(dias_sem)Es muy claro que la actividad disminuye en fines de semana a menos de la mitad habitual y el día más concurrido es el martes.
gender <- ggplot(new_historicos_ecobici, aes(genero_usuario, fill = genero_usuario)) +
geom_bar() +
scale_x_discrete(drop = FALSE)+
ggtitle("Cantidad de usuarios por genero en los registros")
ggplotly(gender)Es notable la diferencia entre la cantidad de hombres que utilizan este servicio contra el genero femenino.
Búsqueda de twits relacionados con ecobici
# creamos una llave en https://dev.twitter.com/apps
consumer_key = "ZLzGFM9OTAR7qajKGxOIaTclA";
consumer_secret = "JHdpn58t2poNdAH5xAdaKk7T3XfQmDiL7WHtylkAaRb4kxLJgz";
# usamos auth básico
secret <- jsonlite::base64_enc(paste(consumer_key, consumer_secret, sep = ":"))
req <- httr::POST("https://api.twitter.com/oauth2/token",
httr::add_headers(
"Authorization" = paste("Basic", gsub("\n", "", secret)),
"Content-Type" = "application/x-www-form-urlencoded;charset=UTF-8"
),
body = "grant_type=client_credentials"
);
# extraemos el token de acceso
httr::stop_for_status(req, "authenticate with twitter")
token <- paste("Bearer", httr::content(req)$access_token)
# llamada al API
url <- "https://api.twitter.com/1.1/search/tweets.json?q=ecobici&result_type=mixed"
req <- httr::GET(url, httr::add_headers(Authorization = token))
json <- httr::content(req, as = "text")
tweets <- jsonlite::fromJSON(json)
substring(tweets$statuses$text, 1, 100)## [1] "Las señales con los brazos son una gran herramienta de comunicación. ¡Utilízalas! Conoce la guía cic"
## [2] "¿Sabes cómo inscribirte a nuestro servicio? ¡Sigue estos pasos y únete a ECOBICI! https://t.co/T6kYk"
## [3] "Ten presente que todo vehículo debe circular en sentido de la vialidad https://t.co/zVzCaltUzt"
## [4] "Si que extraño mi #Ecobici :("
## [5] "RT @ecobici: Las señales con los brazos son una gran herramienta de comunicación. ¡Utilízalas! Conoc"
## [6] "RT @ecobici: No olvidamos lo que amamos #MejorEnBici https://t.co/dfd82Sjw6A"
## [7] "@molekun Hola, por motivos de mantenimiento, nuestra línea de atención es 018003262421. ¿Cómo te pod"
## [8] "@pawspe Hola, por el momento no contamos con proyecto de expansión, puedes solicitar el servicio en "
## [9] "@krn_rmz Hola, gracias por tu reporte, canalizamos la bicicleta a taller para su atención\U0001f527\U0001f6b2"
## [10] "@GSMgo Hola, ¿te encuentras bien? ¿Puedes indicarnos tu número de tarjeta Ecobici?"
## [11] "@ecobici su línea telefónica no sirve y tengo un problema con una cicloestacion"
## [12] "@ecobici"
## [13] "@mak_21 @Vbike_mx Yo \"odio\" más a @Vbike_mx por no hacer algo al respecto, al final como ya pagamos,"
## [14] "@Meelissaae Hola, te pedimos intentar nuevamente o bien acudir a alguno de nuestros módulos de atenc"
## [15] "RT @pasotti_: Con @ecobici, 22% deja de usar su automóvil.\nhttps://t.co/0nrBRyODgt https://t.co/oCdq"